package com.minelx.datamicroscope.core.values;

import com.alibaba.fastjson.JSONObject;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.toMap;

public class VariableGroup {
	private static final String DELIMITER = "_";

	private final String groupName;

	private final String splash;

	private final List<Map<String, String>> possibilities;

	public VariableGroup(String groupName, String splash, List<Map<String, String>> possibilities) {
		this.groupName = groupName;
		this.splash = splash;
		this.possibilities = possibilities;
	}

	public Map<String, String> possibility(String name) {
		return possibilities.stream()
				.filter(which -> which.get(splash).equals(name))
				.findFirst().orElseThrow(() -> new RuntimeException("can't find variable possibility named: " + name));
	}

	public Map<String, String> renderedPossibility(String name) {
		return possibility(name).entrySet().stream()
				.collect(toMap(entry -> groupName + DELIMITER + entry.getKey(), Map.Entry::getValue));
	}

	public List<String> names() {
		return possibilities.stream()
				.map(stringStringMap -> stringStringMap.get(splash))
				.collect(toList());
	}

	public String groupName() {
		return groupName;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o) return true;
		if (o == null || getClass() != o.getClass()) return false;
		VariableGroup that = (VariableGroup) o;
		return groupName.equals(that.groupName) && splash.equals(that.splash) && possibilities.equals(that.possibilities);
	}

	@Override
	public int hashCode() {
		return Objects.hash(groupName, splash, possibilities);
	}

	@Override
	public String toString() {
		return "VariableGroup{" +
				"name='" + groupName + '\'' +
				", splash='" + splash + '\'' +
				", possibilities=" + possibilities +
				'}';
	}

	public static VariableGroup from(JSONObject data) {
		List<Map<String, String>> possibilities = data.getJSONArray("possibilities").toJavaList(JSONObject.class).stream()
				.map(VariableGroup::jsonObjectToStringMap)
				.collect(toList());
		return new VariableGroup(data.getString("name"), data.getString("splash"), possibilities);
	}

	private static Map<String, String> jsonObjectToStringMap(JSONObject jsonObject) {
		return jsonObject.entrySet().stream().collect(toMap(Map.Entry::getKey, entry -> String.valueOf(entry.getValue())));
	}
}
